//Copyright 2012 Trevin Liberty
//GNU GPL v3
//Author: Trevin Liberty

#include "../Swordsmen.h"
#include "SwordsmenOwnedStates.h"
#include "StateFunctions.h"

#include <iostream>
using std::cout;
using std::endl;

//------------------------------------------------------------------------
//
//		WaitS
//
//------------------------------------------------------------------------

WaitS* WaitS::Instance() {
	static WaitS instance;

	return &instance;
}

void WaitS::Enter(Swordsmen* swordsmen) {
	cout << "ENTER WaitS" << endl;
	moveEntityMapCell(swordsmen, swordsmen->getPosIndex());
}

void WaitS::Execute(Swordsmen* swordsmen) {
	//cout << "EXECUTE WaitS" << endl;
	if(!swordsmen->getPath()->empty())
		swordsmen->getStateMachine()->ChangeState(MoveS::Instance());
	else if(swordsmen->hasTarget()) {
		swordsmen->getStateMachine()->ChangeState(AttackS::Instance());
		/*swordsmen->setGivenTarget(true);*/
	}
	else {
		swordsmen->setTarget(someEnemyInRange(swordsmen, 5));
		//if(swordsmen->hasTarget()) {
		//	swordsmen->setGivenTarget(false);
		//}
	}
}

void WaitS::Exit(Swordsmen* swordsmen) {
	cout << "EXIT WaitS" << endl;
}

//------------------------------------------------------------------------
//
//		MoveS
//
//------------------------------------------------------------------------

MoveS* MoveS::Instance() {
	static MoveS instance;

	return &instance;
}

void MoveS::Enter(Swordsmen* swordsmen) {
	cout << "ENTER MoveS" << endl;
	//if no path
	if(swordsmen->getPath()->empty())
		swordsmen->getStateMachine()->ChangeState(WaitS::Instance());
	
	swordsmen->setCurrentDestination(swordsmen->getPath()->front());
	swordsmen->getPath()->pop_front();
}

void MoveS::Execute(Swordsmen* swordsmen) {
	//cout << "EXECUTE MoveS" << endl;
	//If no path
	if(swordsmen->getPath()->empty() && swordsmen->hasArrived()) {
		swordsmen->getStateMachine()->ChangeState(WaitS::Instance());
		return;
	}

	moveUnit(swordsmen);

	if(swordsmen->hasTarget()) {
		/*if(!swordsmen->wasGivenTarget() && swordsmen->outOfRangeGuardPoint()) {
			swordsmen->setGoal(swordsmen->getGuardPoint());
			swordsmen->setTarget(NULL);
		}*/
		if(swordsmen->inRangeOfTarget() && swordsmen->hasArrived()) {
			swordsmen->getStateMachine()->ChangeState(AttackS::Instance());
			return;
		}
	}
}

void MoveS::Exit(Swordsmen* swordsmen) {
	cout << "EXIT MoveS" << endl;
}

//------------------------------------------------------------------------
//
//		AttackS
//
//------------------------------------------------------------------------

AttackS* AttackS::Instance() {
	static AttackS instance;

	return &instance;
}

void AttackS::Enter(Swordsmen* swordsmen) {
	cout << "ENTER AttackS" << endl;
}

void AttackS::Execute(Swordsmen* swordsmen) {
	if(!swordsmen->hasTarget()) {
		swordsmen->getStateMachine()->ChangeState(WaitS::Instance());
		return;
	}

	if(!swordsmen->inRangeOfTarget()) {
		swordsmen->setGoal(swordsmen->getTarget()->getPosIndex());
		swordsmen->getStateMachine()->ChangeState(MoveS::Instance());
		return;
	}

	if(al_get_time() - swordsmen->getLastAttackTime() > swordsmen->getAttackSpeed()) {
		Doohickey* d = swordsmen->getTarget();
		d->addToHealth(swordsmen->getStrength()*-1);
		swordsmen->setLastAttackTime();
	}
}

void AttackS::Exit(Swordsmen* swordsmen) {
	cout << "EXIT AttackS" << endl;
}